#!/usr/bin/env node

/**
 * WordPress WooCommerce爬虫主入口文件
 *
 * 主要功能：
 * - 解析命令行参数，提供用户友好的命令行界面
 * - 验证和更新配置参数
 * - 显示帮助信息和运行状态
 * - 协调爬虫执行流程
 *
 * 支持的命令行参数：
 * - --url, -u: 指定目标分类URL
 * - --limit, -l: 设置最大爬取商品数量
 * - --output, -o: 指定输出目录
 * - --help, -h: 显示帮助信息
 *
 * @file index.js
 * @version 1.0.0
 * @author 项目开发者
 */

// 引入必要的模块
const WordPressWooCommerceCrawler = require('./crawler');  // 核心爬虫类
const config = require('./config');                        // 配置文件
const path = require('path');                              // 路径处理模块

/**
 * 解析命令行参数
 * 支持标准格式(--url, --limit)和简写格式(-u, -l)以及位置参数
 *
 * @returns {Object} 解析后的命令行选项对象
 */
function parseCommandLineArgs() {
    // 获取命令行参数，跳过前两个（node路径和脚本路径）
    const args = process.argv.slice(2);
    
    // 默认选项，使用配置文件中的值
    const options = {
        url: config.TARGET_SITE.CATEGORY_URL,
        limit: config.CRAWL_LIMITS.MAX_PRODUCTS,
        output: config.CSV_EXPORT.OUTPUT_DIR,
        help: false
    };

    // 遍历所有命令行参数
    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        
        switch (arg) {
            case '--url':
            case '-u':
                // 获取下一个参数作为URL值
                options.url = args[++i];
                break;
            case '--limit':
            case '-l':
                // 获取下一个参数作为数量限制，解析为整数，失败则使用默认值
                options.limit = parseInt(args[++i]) || config.CRAWL_LIMITS.MAX_PRODUCTS;
                break;
            case '--output':
            case '-o':
                // 获取下一个参数作为输出目录
                options.output = args[++i];
                break;
            case '--help':
            case '-h':
                // 设置帮助标志
                options.help = true;
                break;
            default:
                // 处理未命名参数（位置参数）
                if (arg.startsWith('http')) {
                    // 如果参数以http开头，认为是URL
                    options.url = arg;
                } else if (!isNaN(parseInt(arg))) {
                    // 如果参数是数字，认为是数量限制
                    options.limit = parseInt(arg);
                }
        }
    }

    return options;
}

/**
 * 显示详细的帮助信息
 * 包含使用说明、参数说明和示例
 */
function showHelp() {
    console.log(`
WordPress WooCommerce商品爬虫

用法:
  node index.js [选项] [URL] [数量]

选项:
  -u, --url <url>        目标分类URL (默认: ${config.TARGET_SITE.CATEGORY_URL})
  -l, --limit <number>   最大爬取商品数量 (默认: ${config.CRAWL_LIMITS.MAX_PRODUCTS})
  -o, --output <dir>     输出目录 (默认: ${config.CSV_EXPORT.OUTPUT_DIR})
  -h, --help             显示此帮助信息

示例:
  node index.js                                      # 使用默认配置
  node index.js --url https://example.com/category/  # 指定URL
  node index.js --limit 10                          # 限制爬取10个商品
  node index.js -u https://example.com/category/ -l 5 -o ./exports
  node index.js https://example.com/category/ 5      # 简写形式

说明:
  - 导出的CSV文件符合WordPress WooCommerce导入格式
  - 文件名包含北京时区时间戳，格式: 分类_年-月-日+星期几缩写+时_分_秒.csv
  - 支持随机延迟，避免被目标网站封禁
  - 支持错误重试和容错处理
    `);
}

/**
 * 验证命令行参数的合法性
 * 检查URL格式、数量限制等关键参数
 *
 * @param {Object} options - 要验证的选项对象
 * @returns {boolean} 参数是否有效
 */
function validateOptions(options) {
    // 检查URL是否提供
    if (!options.url) {
        console.error('错误: 必须提供目标分类URL');
        return false;
    }

    // 检查URL格式是否正确
    if (!options.url.startsWith('http')) {
        console.error('错误: URL必须以 http:// 或 https:// 开头');
        return false;
    }

    // 检查数量限制是否为非负数
    if (options.limit < 0) {
        console.error('错误: 爬取数量必须是非负数');
        return false;
    }

    return true;
}

/**
 * 根据命令行参数更新配置
 * 将用户指定的参数应用到配置对象中
 *
 * @param {Object} options - 命令行选项
 */
function updateConfig(options) {
    // 更新目标URL（如果与默认值不同）
    if (options.url !== config.TARGET_SITE.CATEGORY_URL) {
        config.TARGET_SITE.CATEGORY_URL = options.url;
        console.log(`使用自定义URL: ${options.url}`);
    }

    // 更新爬取限制（如果与默认值不同）
    if (options.limit !== config.CRAWL_LIMITS.MAX_PRODUCTS) {
        config.CRAWL_LIMITS.MAX_PRODUCTS = options.limit;
        console.log(`设置最大爬取数量: ${options.limit}`);
    }

    // 更新输出目录（如果与默认值不同）
    if (options.output !== config.CSV_EXPORT.OUTPUT_DIR) {
        config.CSV_EXPORT.OUTPUT_DIR = options.output;
        console.log(`设置输出目录: ${options.output}`);
    }
}

/**
 * 显示程序启动信息
 * 以美观的格式展示爬虫配置和状态
 */
function showStartupInfo() {
    console.log(`
╔══════════════════════════════════════════════════════════════╗
║                 WordPress WooCommerce爬虫                   ║
║                通用WordPress电商商品数据采集工具             ║
╚══════════════════════════════════════════════════════════════╝

目标网站: ${config.TARGET_SITE.CATEGORY_URL}
最大数量: ${config.CRAWL_LIMITS.MAX_PRODUCTS === 0 ? '无限制' : config.CRAWL_LIMITS.MAX_PRODUCTS}
输出目录: ${config.CSV_EXPORT.OUTPUT_DIR}
随机延迟: ${config.DELAY_CONFIG.ENABLED ? '启用' : '禁用'}

开始爬取...
    `);
}

/**
 * 显示爬取完成后的统计信息和后续操作指南
 *
 * @param {Object} result - 爬虫执行结果对象
 */
function showCompletionInfo(result) {
    console.log(`
╔══════════════════════════════════════════════════════════════╗
║                        爬取任务完成                         ║
╚══════════════════════════════════════════════════════════════╝

统计信息:
  ✅ 成功爬取: ${result.productCount} 个商品
  ⚠️  遇到错误: ${result.errorCount} 次
  ⏱️  总耗时: ${result.duration} 秒
  📁 文件位置: ${result.filePath || '无文件生成'}

使用说明:
  1. 将生成的CSV文件导入到您的WordPress网站
  2. 在WooCommerce > 产品 > 导入中选择CSV文件
  3. 映射字段并开始导入
  4. 检查导入结果并处理任何错误

注意事项:
  - 导入前请备份数据库
  - 检查图片URL是否可访问
  - 验证价格和库存信息
    `);
}

/**
 * 主函数 - 程序的入口点
 * 协调整个爬虫程序的执行流程，包括参数解析、配置更新、爬虫执行和结果展示
 *
 * @async
 */
async function main() {
    try {
        // 步骤1: 解析命令行参数
        const options = parseCommandLineArgs();

        // 步骤2: 如果用户请求帮助信息，显示帮助并退出
        if (options.help) {
            showHelp();
            process.exit(0);  // 正常退出
        }

        // 步骤3: 验证命令行参数的合法性
        if (!validateOptions(options)) {
            process.exit(1);  // 参数验证失败，异常退出
        }

        // 步骤4: 根据命令行参数更新配置
        updateConfig(options);

        // 步骤5: 显示启动信息，展示当前配置
        showStartupInfo();

        // 步骤6: 创建爬虫实例
        const crawler = new WordPressWooCommerceCrawler();

        // 步骤7: 执行爬虫任务
        const result = await crawler.run();

        // 步骤8: 显示爬取完成信息和统计结果
        showCompletionInfo(result);

        // 步骤9: 根据爬虫执行结果设置退出码
        process.exit(result.success ? 0 : 1);

    } catch (error) {
        // 捕获并处理未预期的错误
        console.error('程序执行出错:', error);
        process.exit(1);  // 异常退出
    }
}

// 如果此文件被直接运行（而不是被require导入），则执行主函数
// 这允许此文件既可以作为CLI工具运行，也可以作为模块被其他代码引用
if (require.main === module) {
    main().catch(error => {
        // 捕获主函数中未处理的Promise拒绝
        console.error('未处理的错误:', error);
        process.exit(1);
    });
}

/**
 * 模块导出
 * 允许其他JavaScript文件导入和使用这些功能
 */
module.exports = {
    WordPressWooCommerceCrawler,  // 核心爬虫类
    config,                       // 配置对象
    main                          // 主函数，便于测试或其他用途
};